﻿namespace YidanSoft.Library.EditorUtility.Menus
{
    using System;
    using System.Collections;
    using System.ComponentModel;
    using System.Diagnostics;
    using System.Drawing;
    using System.Drawing.Imaging;
    using System.Drawing.Text;
    using System.Windows.Forms;
    using YidanSoft.Library.EditorUtility.Collections;
    using YidanSoft.Library.EditorUtility.General;
    using YidanSoft.Library.EditorUtility.Win32;

    [DefaultProperty("MenuCommands"), ToolboxItem(false)]
    public class PopupMenu : NativeWindow
    {
        protected Point _aboveScreenPos;
        protected int _borderGap;
        protected PopupMenu _childMenu = null;
        protected Point _currentPoint;
        protected Size _currentSize;
        protected Direction _direction = Direction.Horizontal;
        protected ArrayList _drawCommands = new ArrayList();
        protected int _excludeOffset = 0;
        protected bool _excludeTop = true;
        protected bool _exitLoop = false;
        protected int _extraSize = 0;
        internal FocusCatcher _focusCatcher = null;
        protected bool _grabFocus = false;
        protected readonly int _imageHeight = SystemInformation.SmallIconSize.Height;
        protected readonly int _imageWidth = SystemInformation.SmallIconSize.Width;
        protected Point _lastMousePos = new Point(-1, -1);
        protected bool _layered;
        protected Point _leftScreenPos;
        protected MenuCommandCollection _menuCommands = new MenuCommandCollection();
        protected static ImageList _menuImages = null;
        protected bool _mouseOver = false;
        protected IntPtr _oldFocus = IntPtr.Zero;
        protected MenuControl _parentControl = null;
        protected PopupMenu _parentMenu = null;
        protected bool _popupDown = true;
        protected int _popupItem = -1;
        protected bool _popupRight = true;
        protected static readonly int[,] _position = new int[,] { { 
            2, 1, 0, 1, 4, 3, 4, 5, 4, 4, 2, 6, 5, 3, 1, 10, 
            3, 3, 2, 2, 0, 0
         }, { 
            1, 0, 1, 2, 2, 1, 3, 4, 3, 3, 2, 8, 5, 4, 5, 10, 
            0, 0, 2, 2, 2, 5
         } };
        protected MenuCommand _returnCommand = null;
        protected int _returnDir = 0;
        protected Point _screenPos;
        protected static readonly int _selectionDelay = 400;
        protected bool _showInfrequent = false;
        protected VisualStyle _style = VisualStyle.IDE;
        protected static bool _supportsLayered = false;
        protected System.Drawing.Font _textFont = SystemInformation.MenuFont;
        protected Timer _timer = new Timer();
        protected int _trackItem = -1;
        protected readonly int WM_DISMISS = 0x401;

        static PopupMenu()
        {
            _menuImages = ResourceUtil.LoadImageListResource(System.Type.GetType("YidanSoft.Library.EditorUtility.Menus.PopupMenu"), "Resources.ImagesMenu", "MenuControlImages", new Size(0x10, 0x10), true, new Point(0, 0));
            _supportsLayered = OSFeature.Feature.GetVersionPresent(OSFeature.LayeredWindows) != null;
        }

        public PopupMenu()
        {
            this._timer.Interval = _selectionDelay;
            this._timer.Tick += new EventHandler(this.OnTimerExpire);
        }

        protected void ApplySizeToColumnList(ArrayList columnList, int cellWidth)
        {
            foreach (DrawCommand command in columnList)
            {
                Rectangle drawRect = command.DrawRect;
                command.DrawRect = new Rectangle(drawRect.Left, drawRect.Top, cellWidth, drawRect.Height);
            }
            columnList.Clear();
        }

        protected void ApplyVerticalSeparators(int sepHeight)
        {
            foreach (DrawCommand command in this._drawCommands)
            {
                if (command.VerticalSeparator)
                {
                    Rectangle drawRect = command.DrawRect;
                    command.DrawRect = new Rectangle(drawRect.Left, drawRect.Top, drawRect.Width, sepHeight);
                }
            }
        }

        protected Point CorrectPositionForScreen(Size winSize)
        {
            Point point = this._screenPos;
            int width = SystemInformation.WorkingArea.Width;
            int height = SystemInformation.WorkingArea.Height;
            this._excludeTop = true;
            this._excludeOffset = 0;
            if (this._popupDown)
            {
                if ((point.Y + winSize.Height) > height)
                {
                    if (((this._parentControl != null) && (this._parentMenu == null)) && ((this._aboveScreenPos.Y - winSize.Height) > 0))
                    {
                        point.Y = this._aboveScreenPos.Y - winSize.Height;
                        this._popupDown = false;
                        this._excludeTop = false;
                        this._parentControl.DrawSelectionUpwards();
                    }
                    if ((point.Y + winSize.Height) > height)
                    {
                        if (this._parentMenu != null)
                        {
                            this._popupDown = false;
                            if ((this._aboveScreenPos.Y - winSize.Height) > 0)
                            {
                                point.Y = this._aboveScreenPos.Y - winSize.Height;
                            }
                            else
                            {
                                point.Y = 0;
                            }
                        }
                        else
                        {
                            point.Y = (height - winSize.Height) - 1;
                        }
                    }
                }
            }
            else if ((point.Y - winSize.Height) < 0)
            {
                this._popupDown = true;
                if ((point.Y + winSize.Height) > height)
                {
                    point.Y = (height - winSize.Height) - 1;
                }
            }
            else
            {
                point.Y -= winSize.Height;
            }
            if (this._popupRight)
            {
                if ((point.X + winSize.Width) > width)
                {
                    if (this._parentMenu != null)
                    {
                        this._popupRight = false;
                        point.X = this._leftScreenPos.X - winSize.Width;
                        if (point.X < 0)
                        {
                            point.X = 0;
                        }
                        return point;
                    }
                    int num3 = (width - winSize.Width) - 1;
                    this._excludeOffset = point.X - num3;
                    point.X = num3;
                }
                return point;
            }
            point.X = this._leftScreenPos.X;
            if ((point.X - winSize.Width) < 0)
            {
                this._popupRight = true;
                if ((this._screenPos.X + winSize.Width) > width)
                {
                    point.X = (width - winSize.Width) - 1;
                    return point;
                }
                point.X = this._screenPos.X;
                return point;
            }
            point.X -= winSize.Width;
            return point;
        }

        protected void CreateAndShowWindow()
        {
            this._layered = _supportsLayered && (this._style == VisualStyle.IDE);
            this._layered = false;
            Size winSize = this.GenerateDrawPositions();
            Point point = this.CorrectPositionForScreen(winSize);
            CreateParams cp = new CreateParams();
            cp.Caption = "NativePopupMenu";
            cp.X = point.X;
            cp.Y = point.Y;
            cp.Height = winSize.Height;
            cp.Width = winSize.Width;
            cp.Parent = IntPtr.Zero;
            cp.Style = -2113929216;
            cp.ExStyle = 0x88;
            if (this._layered)
            {
                cp.ExStyle += 0x80000;
            }
            if (this._style == VisualStyle.Plain)
            {
                cp.Style += 0x400000;
            }
            this.CreateHandle(cp);
            if (!this._layered)
            {
                this.SetWindowRegion(winSize);
            }
            this.SetComboBoxesParent();
            WindowsAPI.ShowWindow(base.Handle, 4);
            if (this._layered)
            {
                this._currentPoint = point;
                this._currentSize = winSize;
                this.UpdateLayeredWindow();
                if (this._grabFocus)
                {
                    this.GrabTheFocus();
                }
            }
        }

        public void Dismiss()
        {
            if (base.Handle != IntPtr.Zero)
            {
                this._timer.Stop();
                if (this._childMenu != null)
                {
                    this._childMenu.Dismiss();
                }
                this._exitLoop = true;
                WindowsAPI.ShowWindow(base.Handle, 0);
                WindowsAPI.PostMessage(base.Handle, this.WM_DISMISS, 0, 0);
            }
        }

        protected void DrawAllCommands(Graphics g)
        {
            for (int i = 0; i < this._drawCommands.Count; i++)
            {
                DrawCommand dc = this._drawCommands[i] as DrawCommand;
                this.DrawSingleCommand(g, dc, i == this._trackItem);
            }
        }

        protected void DrawBackground(Graphics g, Rectangle rectWin)
        {
            SolidBrush brush;
            Rectangle rect = new Rectangle(0, 0, (rectWin.Width - 1) - _position[(int) this._style, 0x10], (rectWin.Height - 1) - _position[(int) this._style, 0x11]);
            switch (this._style)
            {
                case VisualStyle.IDE:
                {
                    SolidBrush brush2;
                    int width = (_position[(int) this._style, 5] + this._imageWidth) + _position[(int) this._style, 7];
                    int x = _position[(int) this._style, 1];
                    int y = _position[(int) this._style, 0];
                    int height = ((rect.Height - y) - _position[(int) this._style, 2]) - 1;
                    using (brush = new SolidBrush(SystemColors.ControlLightLight))
                    {
                        g.FillRectangle(brush, rect);
                    }
                    using (Pen pen = new Pen(SystemColors.ControlDark))
                    {
                        g.DrawRectangle(pen, rect);
                        if (this._borderGap > 0)
                        {
                            using (Pen pen2 = new Pen(SystemColors.ControlLight))
                            {
                                if (this._direction == Direction.Horizontal)
                                {
                                    if (this._excludeTop)
                                    {
                                        g.DrawLine(pen2, (rect.Left + 1) + this._excludeOffset, rect.Top, ((rect.Left + this._borderGap) + this._excludeOffset) - 1, rect.Top);
                                    }
                                    else
                                    {
                                        g.DrawLine(pen2, (rect.Left + 1) + this._excludeOffset, rect.Bottom, ((rect.Left + this._borderGap) + this._excludeOffset) - 1, rect.Bottom);
                                    }
                                }
                                else if (this._excludeTop)
                                {
                                    g.DrawLine(pen2, rect.Left, (rect.Top + 1) + this._excludeOffset, rect.Left, ((rect.Top + this._borderGap) + this._excludeOffset) - 1);
                                }
                                else
                                {
                                    g.DrawLine(pen2, rect.Left, (rect.Bottom - 1) - this._excludeOffset, rect.Left, ((rect.Bottom - this._borderGap) - this._excludeOffset) - 1);
                                }
                            }
                        }
                    }
                    Rectangle rectangle2 = new Rectangle(x, y, width, height);
                    g.FillRectangle(SystemBrushes.ControlLight, rectangle2);
                    foreach (DrawCommand command in this._drawCommands)
                    {
                        if (command.Separator && command.VerticalSeparator)
                        {
                            rectangle2.X = command.DrawRect.Right;
                            g.FillRectangle(SystemBrushes.ControlLight, rectangle2);
                        }
                    }
                    int num5 = rect.Right + 1;
                    int num6 = rect.Top + _position[(int) this._style, 0x11];
                    int num7 = rect.Bottom + 1;
                    int num8 = rect.Left + _position[(int) this._style, 0x10];
                    int num9 = rect.Left + this._excludeOffset;
                    int num10 = (rect.Left + this._excludeOffset) + this._borderGap;
                    if (this._layered)
                    {
                        brush2 = new SolidBrush(Color.FromArgb(0x40, 0, 0, 0));
                    }
                    else
                    {
                        brush2 = new SolidBrush(SystemColors.ControlDark);
                    }
                    if (((this._borderGap > 0) && !this._excludeTop) && (this._direction == Direction.Horizontal))
                    {
                        int num11 = rectWin.Width;
                        if (num9 >= num8)
                        {
                            g.FillRectangle(brush2, num8, num7, num9 - num8, _position[(int) this._style, 0x11]);
                        }
                        if (num10 <= num11)
                        {
                            g.FillRectangle(brush2, num10, num7, num11 - num10, _position[(int) this._style, 0x11]);
                        }
                    }
                    else
                    {
                        if (!((this._direction != Direction.Vertical) || this._excludeTop))
                        {
                            num8 = 0;
                        }
                        g.FillRectangle(brush2, num8, num7, num5, _position[(int) this._style, 0x11]);
                    }
                    g.FillRectangle(brush2, num5, num6, _position[(int) this._style, 0x10], num7 - num6);
                    brush2.Dispose();
                    if (((this._borderGap > 0) && !this._excludeTop) && (this._direction == Direction.Horizontal))
                    {
                        using (SolidBrush brush3 = new SolidBrush(SystemColors.ControlLight))
                        {
                            g.FillRectangle(brush3, new Rectangle(num9, num7 - 1, num10 - num9, _position[(int) this._style, 0x11] + 1));
                        }
                        using (Pen pen3 = new Pen(SystemColors.ControlDark))
                        {
                            g.DrawLine(pen3, num9, num7 - 1, num9, rectWin.Height);
                            g.DrawLine(pen3, num10, num7 - 1, num10, rectWin.Height);
                        }
                    }
                    break;
                }
                case VisualStyle.Plain:
                    using (brush = new SolidBrush(SystemColors.Control))
                    {
                        g.FillRectangle(brush, rectWin);
                    }
                    break;
            }
            if (this._menuCommands.ExtraText.Length > 0)
            {
                this.DrawColumn(g, rect);
            }
        }

        protected void DrawColumn(Graphics g, Rectangle main)
        {
            Rectangle rect = new Rectangle(main.Left, main.Top, this._extraSize - _position[(int) this._style, 20], main.Height);
            Brush extraBackBrush = null;
            bool flag = true;
            if (this._menuCommands.ExtraBackBrush != null)
            {
                extraBackBrush = this._menuCommands.ExtraBackBrush;
                flag = false;
                rect.Width++;
            }
            else
            {
                extraBackBrush = new SolidBrush(this._menuCommands.ExtraBackColor);
            }
            g.FillRectangle(extraBackBrush, rect);
            if (flag)
            {
                extraBackBrush.Dispose();
            }
            rect.X += _position[(int) this._style, 0x12];
            rect.Y += _position[(int) this._style, 0x13];
            rect.Width -= _position[(int) this._style, 0x12] * 2;
            rect.Height -= _position[(int) this._style, 0x13] * 2;
            if (this._style == VisualStyle.Plain)
            {
                rect.Height -= SystemInformation.Border3DSize.Height * 2;
            }
            StringFormat drawFormat = new StringFormat();
            drawFormat.FormatFlags = StringFormatFlags.NoClip | StringFormatFlags.NoWrap | StringFormatFlags.DirectionVertical;
            drawFormat.Alignment = StringAlignment.Near;
            drawFormat.LineAlignment = StringAlignment.Center;
            Brush drawBrush = null;
            bool flag2 = true;
            if (this._menuCommands.ExtraTextBrush != null)
            {
                drawBrush = this._menuCommands.ExtraTextBrush;
                flag2 = false;
            }
            else
            {
                drawBrush = new SolidBrush(this._menuCommands.ExtraTextColor);
            }
            TextUtil.DrawReverseString(g, this._menuCommands.ExtraText, this._menuCommands.ExtraFont, rect, drawBrush, drawFormat);
            if (flag2)
            {
                drawBrush.Dispose();
            }
        }

        internal void DrawSingleCommand(Graphics g, DrawCommand dc, bool hotCommand)
        {
            Rectangle rectangle3;
            Pen pen;
            SolidBrush brush;
            SolidBrush brush2;
            Color control;
            Rectangle rectangle4;
            int num11;
            SolidBrush brush3;
            Pen pen5;
            Rectangle drawRect = dc.DrawRect;
            MenuCommand menuCommand = dc.MenuCommand;
            int num = _position[(int) this._style, 8];
            int num2 = _position[(int) this._style, 5];
            int num3 = _position[(int) this._style, 7];
            int x = drawRect.Left + num2;
            int width = (num2 + this._imageWidth) + num3;
            int num6 = (_position[(int) this._style, 10] + _position[(int) this._style, 11]) + _position[(int) this._style, 12];
            int num7 = (drawRect.Right - _position[(int) this._style, 12]) - _position[(int) this._style, 11];
            int num8 = (num7 - _position[(int) this._style, 10]) - _position[(int) this._style, 9];
            if (!dc.Expansion)
            {
                if (dc.Separator)
                {
                    Pen pen4;
                    ButtonBorderStyle inset;
                    ButtonBorderStyle style2;
                    Rectangle rectangle5;
                    if (dc.VerticalSeparator)
                    {
                        switch (this._style)
                        {
                            case VisualStyle.IDE:
                                using (pen4 = new Pen(SystemColors.ControlDark))
                                {
                                    g.DrawLine(pen4, drawRect.Left, drawRect.Top, drawRect.Left, drawRect.Bottom);
                                }
                                return;

                            case VisualStyle.Plain:
                                control = SystemColors.Control;
                                inset = ButtonBorderStyle.Inset;
                                style2 = ButtonBorderStyle.Inset;
                                rectangle5 = new Rectangle(drawRect.Left + 1, drawRect.Top, 2, drawRect.Height);
                                ControlPaint.DrawBorder(g, rectangle5, control, 1, inset, control, 0, style2, control, 1, inset, control, 0, style2);
                                return;
                        }
                    }
                    else
                    {
                        switch (this._style)
                        {
                            case VisualStyle.IDE:
                                rectangle4 = new Rectangle(drawRect.Left, drawRect.Top, width, drawRect.Height);
                                g.FillRectangle(new SolidBrush(ColorUtil.VSNetBackgroundColor), drawRect);
                                g.FillRectangle(new SolidBrush(ColorUtil.VSNetControlColor), rectangle4);
                                using (pen4 = new Pen(Color.FromArgb(0x4b, SystemColors.MenuText)))
                                {
                                    g.DrawLine(pen4, (int) ((drawRect.Left + width) + num), (int) (drawRect.Top + 1), (int) (drawRect.Right - 4), (int) (drawRect.Top + 1));
                                }
                                return;

                            case VisualStyle.Plain:
                                control = SystemColors.Control;
                                inset = ButtonBorderStyle.Inset;
                                style2 = ButtonBorderStyle.Inset;
                                rectangle5 = new Rectangle(drawRect.Left + 2, drawRect.Top + 1, drawRect.Width - 4, 2);
                                ControlPaint.DrawBorder(g, rectangle5, control, 0, style2, control, 1, inset, control, 0, style2, control, 1, inset);
                                return;
                        }
                    }
                    return;
                }
                if (hotCommand && (menuCommand.ComboBox == null))
                {
                    switch (this._style)
                    {
                        case VisualStyle.IDE:
                            rectangle3 = new Rectangle(drawRect.Left + 1, drawRect.Top, drawRect.Width - 3, drawRect.Height - 1);
                            using (pen = new Pen(ColorUtil.VSNetBorderColor))
                            {
                                using (brush = new SolidBrush(Color.White))
                                {
                                    g.FillRectangle(brush, rectangle3);
                                }
                                using (brush2 = new SolidBrush(Color.FromArgb(70, ColorUtil.VSNetBorderColor)))
                                {
                                    g.FillRectangle(brush2, rectangle3);
                                    g.DrawRectangle(pen, rectangle3);
                                }
                            }
                            goto Label_08C5;

                        case VisualStyle.Plain:
                            using (brush2 = new SolidBrush(ColorUtil.VSNetBorderColor))
                            {
                                g.FillRectangle(brush2, drawRect);
                            }
                            goto Label_08C5;
                    }
                }
                else
                {
                    switch (this._style)
                    {
                        case VisualStyle.IDE:
                            using (brush = new SolidBrush(ColorUtil.VSNetBackgroundColor))
                            {
                                g.FillRectangle(brush, new Rectangle(drawRect.Left + 1, drawRect.Top, drawRect.Width - 1, drawRect.Height));
                            }
                            rectangle4 = new Rectangle(drawRect.Left, drawRect.Top, width, drawRect.Height);
                            g.FillRectangle(new SolidBrush(ColorUtil.VSNetControlColor), rectangle4);
                            if (menuCommand.ComboBox != null)
                            {
                                menuCommand.ComboBox.Left = (drawRect.Left + width) + 2;
                                menuCommand.ComboBox.Top = drawRect.Top + ((drawRect.Height - menuCommand.ComboBox.Height) / 2);
                            }
                            goto Label_08C5;

                        case VisualStyle.Plain:
                            g.FillRectangle(SystemBrushes.Control, new Rectangle(drawRect.Left, drawRect.Top, drawRect.Width, drawRect.Height));
                            goto Label_08C5;
                    }
                }
                goto Label_08C5;
            }
            Rectangle rect = drawRect;
            if (this._style == VisualStyle.IDE)
            {
                rect.X += width;
                rect.Width -= width;
            }
            int num9 = rect.Left + ((rect.Width - this._imageHeight) / 2);
            int y = rect.Top + ((rect.Height - this._imageHeight) / 2);
            switch (this._style)
            {
                case VisualStyle.IDE:
                    g.FillRectangle(SystemBrushes.ControlLightLight, rect);
                    break;

                case VisualStyle.Plain:
                    g.FillRectangle(SystemBrushes.Control, rect);
                    break;
            }
            if (hotCommand)
            {
                switch (this._style)
                {
                    case VisualStyle.IDE:
                        rectangle3 = new Rectangle(drawRect.Left + 1, drawRect.Top, drawRect.Width - 3, drawRect.Height - 1);
                        using (pen = new Pen(ColorUtil.VSNetBorderColor))
                        {
                            using (brush = new SolidBrush(Color.White))
                            {
                                g.FillRectangle(brush, rectangle3);
                            }
                            using (brush2 = new SolidBrush(Color.FromArgb(70, ColorUtil.VSNetBorderColor)))
                            {
                                g.FillRectangle(brush2, rectangle3);
                                g.DrawRectangle(pen, rectangle3);
                            }
                        }
                        goto Label_045C;

                    case VisualStyle.Plain:
                        rect.Inflate(-2, -2);
                        control = SystemColors.Control;
                        using (Pen pen2 = new Pen(SystemColors.ControlLightLight))
                        {
                            using (Pen pen3 = new Pen(SystemColors.ControlDarkDark))
                            {
                                g.DrawLine(pen2, rect.Right, rect.Top, rect.Left, rect.Top);
                                g.DrawLine(pen2, rect.Left, rect.Top, rect.Left, rect.Bottom);
                                g.DrawLine(pen3, rect.Left, rect.Bottom, rect.Right, rect.Bottom);
                                g.DrawLine(pen3, rect.Right, rect.Bottom, rect.Right, rect.Top);
                            }
                        }
                        goto Label_045C;
                }
            }
            else
            {
                switch (this._style)
                {
                    case VisualStyle.IDE:
                        using (brush = new SolidBrush(SystemColors.ControlLightLight))
                        {
                            g.FillRectangle(brush, new Rectangle(drawRect.Left + 1, drawRect.Top, drawRect.Width - 1, drawRect.Height));
                        }
                        rectangle4 = new Rectangle(drawRect.Left, drawRect.Top, width, drawRect.Height);
                        g.FillRectangle(SystemBrushes.Control, rectangle4);
                        goto Label_045C;

                    case VisualStyle.Plain:
                        g.FillRectangle(SystemBrushes.Control, new Rectangle(drawRect.Left, drawRect.Top, drawRect.Width, drawRect.Height));
                        goto Label_045C;
                }
            }
        Label_045C:
            g.DrawImage(_menuImages.Images[6], num9, y);
            return;
        Label_08C5:
            num11 = (drawRect.Left + width) + num;
            Rectangle layoutRectangle = new Rectangle(num11, drawRect.Top, num8 - num11, drawRect.Height);
            StringFormat format = new StringFormat();
            format.FormatFlags = StringFormatFlags.NoClip | StringFormatFlags.NoWrap;
            format.Alignment = StringAlignment.Near;
            format.LineAlignment = StringAlignment.Center;
            format.HotkeyPrefix = HotkeyPrefix.Show;
            if (menuCommand.Enabled)
            {
                if (!(hotCommand && (this._style != VisualStyle.IDE)))
                {
                    brush3 = new SolidBrush(SystemColors.MenuText);
                }
                else
                {
                    brush3 = new SolidBrush(SystemColors.HighlightText);
                }
            }
            else
            {
                brush3 = new SolidBrush(SystemColors.GrayText);
            }
            Rectangle rectangle7 = layoutRectangle;
            rectangle7.Offset(1, 1);
            if (menuCommand.Enabled || (this._style == VisualStyle.IDE))
            {
                g.DrawString(menuCommand.Text, this._textFont, brush3, layoutRectangle, format);
            }
            else
            {
                using (brush = new SolidBrush(SystemColors.HighlightText))
                {
                    g.DrawString(menuCommand.Text, this._textFont, brush, rectangle7, format);
                }
                g.DrawString(menuCommand.Text, this._textFont, brush3, layoutRectangle, format);
            }
            if (menuCommand.Shortcut != Shortcut.None)
            {
                format.Alignment = StringAlignment.Far;
                if (menuCommand.Enabled || (this._style == VisualStyle.IDE))
                {
                    g.DrawString(this.GetShortcutText(menuCommand.Shortcut), this._textFont, brush3, layoutRectangle, format);
                }
                else
                {
                    using (brush = new SolidBrush(SystemColors.HighlightText))
                    {
                        g.DrawString(this.GetShortcutText(menuCommand.Shortcut), this._textFont, brush, rectangle7, format);
                    }
                    g.DrawString(this.GetShortcutText(menuCommand.Shortcut), this._textFont, brush3, layoutRectangle, format);
                }
            }
            int num12 = drawRect.Top + ((drawRect.Height - this._imageHeight) / 2);
            Image image = null;
            if (!menuCommand.Checked)
            {
                try
                {
                    if ((menuCommand.ImageList != null) && (menuCommand.ImageIndex >= 0))
                    {
                        image = menuCommand.ImageList.Images[menuCommand.ImageIndex];
                    }
                    else if (menuCommand.Image != null)
                    {
                        image = menuCommand.Image;
                    }
                }
                catch (Exception)
                {
                    image = _menuImages.Images[7];
                }
                goto Label_0C8C;
            }
            switch (this._style)
            {
                case VisualStyle.IDE:
                    if (!menuCommand.Enabled)
                    {
                        pen5 = new Pen(SystemColors.GrayText);
                        break;
                    }
                    pen5 = new Pen(ColorUtil.VSNetBorderColor);
                    break;

                default:
                    goto Label_0B8F;
            }
            g.DrawRectangle(pen5, new Rectangle(x - 1, num12 - 1, this._imageHeight + 2, this._imageWidth + 2));
            pen5.Dispose();
        Label_0B8F:
            if (menuCommand.RadioCheck)
            {
                if (hotCommand && (this._style == VisualStyle.Plain))
                {
                    image = _menuImages.Images[4];
                }
                else
                {
                    image = _menuImages.Images[1];
                }
            }
            else if (hotCommand && (this._style == VisualStyle.Plain))
            {
                image = _menuImages.Images[3];
            }
            else
            {
                image = _menuImages.Images[0];
            }
        Label_0C8C:
            if (image != null)
            {
                if (menuCommand.Enabled)
                {
                    if ((hotCommand && !menuCommand.Checked) && (this._style == VisualStyle.IDE))
                    {
                        ControlPaint.DrawImageDisabled(g, image, x + 1, num12 + 1, SystemColors.HighlightText);
                        g.DrawImage(image, (int) (x - 1), (int) (num12 - 1));
                    }
                    else
                    {
                        g.DrawImage(image, x, num12);
                    }
                }
                else
                {
                    ControlPaint.DrawImageDisabled(g, image, x, num12, SystemColors.HighlightText);
                }
            }
            if (dc.SubMenu)
            {
                if (menuCommand.Enabled)
                {
                    int num13 = 2;
                    if (hotCommand && (this._style == VisualStyle.Plain))
                    {
                        num13 = 5;
                    }
                    g.DrawImage(_menuImages.Images[num13], num7, num12);
                }
                else
                {
                    ControlPaint.DrawImageDisabled(g, _menuImages.Images[2], num7, num12, SystemColors.HighlightText);
                }
            }
        }

        protected Size GenerateDrawPositions()
        {
            this._drawCommands = new ArrayList();
            int height = (_position[(int) this._style, 4] + this._imageHeight) + _position[(int) this._style, 6];
            int width = ((((((_position[(int) this._style, 5] + this._imageWidth) + _position[(int) this._style, 7]) + _position[(int) this._style, 8]) + _position[(int) this._style, 9]) + _position[(int) this._style, 10]) + _position[(int) this._style, 11]) + _position[(int) this._style, 12];
            int num3 = this._textFont.Height;
            if (num3 < height)
            {
                num3 = height;
            }
            int num4 = SystemInformation.WorkingArea.Height;
            int x = _position[(int) this._style, 1];
            int y = _position[(int) this._style, 0];
            int num7 = y;
            int cellWidth = width;
            int num9 = 0;
            int sepHeight = 0;
            int row = 0;
            int col = 0;
            bool flag = false;
            IntPtr dC = WindowsAPI.GetDC(IntPtr.Zero);
            ArrayList columnList = new ArrayList();
            using (Graphics graphics = Graphics.FromHdc(dC))
            {
                Rectangle rectangle;
                DrawCommand command3;
                if (this._menuCommands.ExtraText.Length > 0)
                {
                    int num13 = ((int) graphics.MeasureString(this._menuCommands.ExtraText, this._menuCommands.ExtraFont).Height) + 1;
                    this._extraSize = (num13 + _position[(int) this._style, 20]) + (_position[(int) this._style, 0x12] * 2);
                    x += this._extraSize;
                    num9 = this._extraSize;
                }
                foreach (MenuCommand command in this._menuCommands)
                {
                    command.OnUpdate(EventArgs.Empty);
                    if (command.Visible && ((command.MenuCommands.Count <= 0) || command.MenuCommands.VisibleItems()))
                    {
                        int num16;
                        DrawCommand command2;
                        if (!(!command.Infrequent || this._showInfrequent))
                        {
                            flag = true;
                            continue;
                        }
                        int num14 = 0;
                        int num15 = 0;
                        if (command.Break)
                        {
                            row = 0;
                            col++;
                            this.ApplySizeToColumnList(columnList, cellWidth);
                            x += cellWidth;
                            num16 = _position[(int) this._style, 14];
                            command2 = new DrawCommand(new Rectangle(x, 0, num16, 0), false);
                            this._drawCommands.Add(command2);
                            x += num16;
                            num7 = y;
                            num9 += cellWidth + num16;
                            cellWidth = width;
                        }
                        if (command.Text == "-")
                        {
                            num14 = width;
                            num15 = _position[(int) this._style, 13];
                        }
                        else
                        {
                            num15 = num3;
                            SizeF ef = graphics.MeasureString(command.Text, this._textFont);
                            num14 = (width + ((int) ef.Width)) + 1;
                            if (command.Shortcut != Shortcut.None)
                            {
                                ef = graphics.MeasureString(this.GetShortcutText(command.Shortcut), this._textFont);
                                num14 += (_position[(int) this._style, 15] + ((int) ef.Width)) + 1;
                            }
                            if (command.ComboBox != null)
                            {
                                num14 += command.ComboBox.Width;
                            }
                        }
                        if ((num7 + num15) >= num4)
                        {
                            row = 0;
                            col++;
                            this.ApplySizeToColumnList(columnList, cellWidth);
                            x += cellWidth;
                            num16 = _position[(int) this._style, 14];
                            command2 = new DrawCommand(new Rectangle(x, y, num16, 0), false);
                            this._drawCommands.Add(command2);
                            x += num16;
                            num7 = y;
                            num9 += cellWidth + num16;
                            cellWidth = width;
                        }
                        rectangle = new Rectangle(x, num7, num14, num15);
                        command3 = new DrawCommand(command, rectangle, row, col);
                        this._drawCommands.Add(command3);
                        columnList.Add(command3);
                        if (num14 > cellWidth)
                        {
                            cellWidth = num14;
                        }
                        num7 += num15;
                        if (num7 > sepHeight)
                        {
                            sepHeight = num7;
                        }
                        row++;
                    }
                }
                if (flag)
                {
                    rectangle = new Rectangle(x, num7, width, height);
                    command3 = new DrawCommand(rectangle, true);
                    this._drawCommands.Add(command3);
                    columnList.Add(command3);
                    num7 += height;
                    if (num7 > sepHeight)
                    {
                        sepHeight = num7;
                    }
                }
                this.ApplySizeToColumnList(columnList, cellWidth);
            }
            WindowsAPI.ReleaseDC(IntPtr.Zero, dC);
            int num17 = ((_position[(int) this._style, 1] + num9) + cellWidth) + _position[(int) this._style, 3];
            int num18 = (_position[(int) this._style, 0] + sepHeight) + _position[(int) this._style, 2];
            this.ApplyVerticalSeparators(sepHeight);
            int num19 = _position[(int) this._style, 0x11];
            int num20 = _position[(int) this._style, 0x10];
            if (this._style == VisualStyle.Plain)
            {
                num19 += SystemInformation.Border3DSize.Width * 2;
                num20 += SystemInformation.Border3DSize.Height * 2;
            }
            return new Size(num17 + num19, num18 + num20);
        }

        protected string GetShortcutText(Shortcut shortcut)
        {
            char ch = (char) ((ushort) (shortcut & ((Shortcut) 0xffff)));
            if ((ch >= '0') && (ch <= '9'))
            {
                string str = "";
                int num = (int) (((long) shortcut) & 0xffff0000L);
                if ((num & 0x10000) != 0)
                {
                    str = str + "Shift+";
                }
                if ((num & 0x20000) != 0)
                {
                    str = str + "Ctrl+";
                }
                if ((num & 0x40000) != 0)
                {
                    str = str + "Alt+";
                }
                return (str + ch);
            }
            return TypeDescriptor.GetConverter(typeof(Keys)).ConvertToString((Keys) shortcut);
        }

        protected void GrabTheFocus()
        {
            this._oldFocus = WindowsAPI.GetFocus();
            if (this._oldFocus != IntPtr.Zero)
            {
                IntPtr parent = WindowsAPI.GetParent(this._oldFocus);
                if (parent != IntPtr.Zero)
                {
                    this._focusCatcher = new FocusCatcher(parent);
                    WindowsAPI.SetFocus(this._focusCatcher.Handle);
                    WindowsAPI.ReleaseCapture();
                }
            }
            this._grabFocus = false;
        }

        protected MenuCommand InternalTrackPopup(bool selectFirst)
        {
            this._returnCommand = null;
            this._trackItem = -1;
            this._exitLoop = false;
            this._mouseOver = false;
            this._returnDir = 0;
            bool flag = false;
            this.CreateAndShowWindow();
            YidanSoft.Library.EditorUtility.Win32.MSG msg = new YidanSoft.Library.EditorUtility.Win32.MSG();
            if (selectFirst)
            {
                this.ProcessKeyDown();
            }
            while (!this._exitLoop)
            {
                if (WindowsAPI.WaitMessage())
                {
                    while (!this._exitLoop && WindowsAPI.PeekMessage(ref msg, 0, 0, 0, 0))
                    {
                        DrawCommand command;
                        int num;
                        bool flag2 = WindowsAPI.GetParent(msg.hwnd) == base.Handle;
                        bool flag3 = this.IsComboBoxList(msg.hwnd);
                        if (((((msg.message == 0x201) || (msg.message == 0x207)) || ((msg.message == 0x204) || (msg.message == 0xa1))) || (msg.message == 0xa7)) || (msg.message == 0xa4))
                        {
                            if ((msg.hwnd != base.Handle) && ((!this.ParentWantsMouseMessage(ref msg) && !flag2) && !flag3))
                            {
                                this._exitLoop = true;
                                flag = true;
                                if ((this._parentControl != null) && (msg.hwnd == this._parentControl.Handle))
                                {
                                    flag = false;
                                }
                            }
                        }
                        else
                        {
                            YidanSoft.Library.EditorUtility.Win32.MSG msg2;
                            if (msg.message == 0x200)
                            {
                                if (msg.hwnd != base.Handle)
                                {
                                    if (this._mouseOver)
                                    {
                                        this.OnWM_MOUSELEAVE();
                                    }
                                    if (!((this.ParentWantsMouseMessage(ref msg) || flag2) || flag3))
                                    {
                                        msg2 = new YidanSoft.Library.EditorUtility.Win32.MSG();
                                        WindowsAPI.GetMessage(ref msg2, 0, 0, 0);
                                        flag = true;
                                    }
                                }
                            }
                            else
                            {
                                if ((msg.message == 260) && (((int) msg.wParam) == 0x12))
                                {
                                    this._exitLoop = true;
                                }
                                if (msg.message == 0x100)
                                {
                                    int wParam = (int) msg.wParam;
                                    if (wParam != 13)
                                    {
                                        switch (wParam)
                                        {
                                            case 0x25:
                                                this.ProcessKeyLeft();
                                                goto Label_03AB;

                                            case 0x26:
                                                this.ProcessKeyUp();
                                                goto Label_03AB;

                                            case 0x27:
                                                if (this.ProcessKeyRight())
                                                {
                                                    flag = true;
                                                }
                                                goto Label_03AB;

                                            case 40:
                                                this.ProcessKeyDown();
                                                goto Label_03AB;

                                            case 0x1b:
                                                goto Label_0353;
                                        }
                                        goto Label_035C;
                                    }
                                    if (this._trackItem != -1)
                                    {
                                        command = this._drawCommands[this._trackItem] as DrawCommand;
                                        if (command.SubMenu)
                                        {
                                            msg2 = new YidanSoft.Library.EditorUtility.Win32.MSG();
                                            WindowsAPI.GetMessage(ref msg2, 0, 0, 0);
                                            this.OperateSubMenu(this._trackItem, false);
                                            flag = true;
                                        }
                                        else if (command.Expansion)
                                        {
                                            this.RegenerateExpansion();
                                        }
                                        else
                                        {
                                            this._returnCommand = command.MenuCommand;
                                            this._exitLoop = true;
                                        }
                                    }
                                }
                            }
                        }
                        goto Label_03AB;
                    Label_0353:
                        this._exitLoop = true;
                        goto Label_03AB;
                    Label_035C:
                        num = this.ProcessMnemonicKey((char) ((int) msg.wParam));
                        if (num != -1)
                        {
                            command = this._drawCommands[num] as DrawCommand;
                            this._returnCommand = command.MenuCommand;
                            this._exitLoop = true;
                        }
                    Label_03AB:
                        if (!flag)
                        {
                            if (WindowsAPI.GetMessage(ref msg, 0, 0, 0))
                            {
                                WindowsAPI.TranslateMessage(ref msg);
                                WindowsAPI.DispatchMessage(ref msg);
                            }
                        }
                        else
                        {
                            flag = false;
                        }
                    }
                }
            }
            if (this._oldFocus != IntPtr.Zero)
            {
                this.ReturnTheFocus();
            }
            this.UnsetComboBoxesParent();
            WindowsAPI.ShowWindow(base.Handle, 0);
            this.DestroyHandle();
            if ((this._parentMenu == null) && (this._returnCommand != null))
            {
                this._returnCommand.OnClick(EventArgs.Empty);
            }
            return this._returnCommand;
        }

        protected MenuCommand InternalTrackPopup(Point screenPosTR, Point screenPosTL, MenuCommandCollection menuCollection, PopupMenu parentMenu, bool selectFirst, MenuControl parentControl, bool popupRight, bool popupDown, ref int returnDir)
        {
            this._direction = Direction.Horizontal;
            this._parentControl = parentControl;
            this._parentMenu = parentMenu;
            MenuCommandCollection commands = this._menuCommands;
            this._menuCommands = menuCollection;
            this._screenPos = screenPosTR;
            this._aboveScreenPos = screenPosTR;
            this._leftScreenPos = screenPosTL;
            this._popupRight = popupRight;
            this._popupDown = popupDown;
            MenuCommand command = this.InternalTrackPopup(selectFirst);
            this._menuCommands = commands;
            this._parentControl = null;
            this._parentMenu = null;
            returnDir = this._returnDir;
            return command;
        }

        private bool IsComboBoxList(IntPtr hWnd)
        {
            STRINGBUFFER stringbuffer;
            WindowsAPI.GetClassName(hWnd, out stringbuffer, 80);
            return (stringbuffer.szText == "ComboLBox");
        }

        protected void OnTimerExpire(object sender, EventArgs e)
        {
            this._timer.Stop();
            bool flag = true;
            if (this._childMenu != null)
            {
                if (this._popupItem != this._trackItem)
                {
                    WindowsAPI.PostMessage(this._childMenu.Handle, this.WM_DISMISS, 0, 0);
                }
                else
                {
                    flag = false;
                }
            }
            if (flag && (this._trackItem != -1))
            {
                DrawCommand command = this._drawCommands[this._trackItem] as DrawCommand;
                if (command.SubMenu)
                {
                    this.OperateSubMenu(this._trackItem, false);
                }
                else if (command.Expansion)
                {
                    this.RegenerateExpansion();
                }
            }
        }

        protected void OnWM_ACTIVATEAPP(ref Message m)
        {
            this._timer.Stop();
            this._exitLoop = true;
        }

        protected void OnWM_DISMISS()
        {
            if (this._childMenu != null)
            {
                WindowsAPI.PostMessage(this._childMenu.Handle, this.WM_DISMISS, 0, 0);
            }
            this._returnCommand = null;
            this._timer.Stop();
            this._exitLoop = true;
            WindowsAPI.ShowWindow(base.Handle, 0);
            this.DestroyHandle();
        }

        protected void OnWM_MOUSEACTIVATE(ref Message m)
        {
            m.Result = (IntPtr) 3L;
        }

        protected void OnWM_MOUSELEAVE()
        {
            if ((this._trackItem != -1) && (this._childMenu == null))
            {
                this.SwitchSelection(this._trackItem, -1, false, false);
            }
            this._mouseOver = false;
            this._lastMousePos = new Point(-1, -1);
        }

        protected void OnWM_MOUSEMOVE(ref Message m)
        {
            if (this._parentMenu != null)
            {
                this._parentMenu.SubMenuMovement();
            }
            if (!this._mouseOver)
            {
                TRACKMOUSEEVENTS tme = new TRACKMOUSEEVENTS();
                tme.cbSize = 0x10;
                tme.dwFlags = 2;
                tme.hWnd = base.Handle;
                tme.dwHoverTime = 0;
                WindowsAPI.TrackMouseEvent(ref tme);
                this._mouseOver = true;
            }
            int x = ((int) m.LParam) & 0xffff;
            int y = (((int) m.LParam) & -65536) >> 0x10;
            Point pt = new Point(x, y);
            if (this._lastMousePos != pt)
            {
                for (int i = 0; i < this._drawCommands.Count; i++)
                {
                    DrawCommand command = this._drawCommands[i] as DrawCommand;
                    if (command.DrawRect.Contains(pt) && (this._trackItem != i))
                    {
                        this.SwitchSelection(this._trackItem, i, true, false);
                    }
                }
                this._lastMousePos = pt;
            }
        }

        protected void OnWM_PAINT(ref Message m)
        {
            if (this._grabFocus)
            {
                this.GrabTheFocus();
            }
            YidanSoft.Library.EditorUtility.Win32.PAINTSTRUCT ps = new YidanSoft.Library.EditorUtility.Win32.PAINTSTRUCT();
            IntPtr hdc = WindowsAPI.BeginPaint(m.HWnd, ref ps);
            YidanSoft.Library.EditorUtility.Win32.RECT rect = new YidanSoft.Library.EditorUtility.Win32.RECT();
            WindowsAPI.GetWindowRect(base.Handle, ref rect);
            Rectangle rectWin = new Rectangle(0, 0, rect.right - rect.left, rect.bottom - rect.top);
            using (Graphics graphics = Graphics.FromHdc(hdc))
            {
                Bitmap image = new Bitmap(rectWin.Width, rectWin.Height);
                using (Graphics graphics2 = Graphics.FromImage(image))
                {
                    this.DrawBackground(graphics2, rectWin);
                    this.DrawAllCommands(graphics2);
                }
                graphics.DrawImageUnscaled(image, 0, 0);
            }
            WindowsAPI.EndPaint(m.HWnd, ref ps);
        }

        protected void OnWM_SETCURSOR(ref Message m)
        {
            WindowsAPI.SetCursor(WindowsAPI.LoadCursor(IntPtr.Zero, 0x7f00));
        }

        protected void OnWM_XBUTTONUP(ref Message m)
        {
            DrawCommand command;
            int x = ((int) m.LParam) & 0xffff;
            int y = (((int) m.LParam) & -65536) >> 0x10;
            Point pt = new Point(x, y);
            for (int i = 0; i < this._drawCommands.Count; i++)
            {
                command = this._drawCommands[i] as DrawCommand;
                if (command.DrawRect.Contains(pt) && (this._trackItem != i))
                {
                    this.SwitchSelection(this._trackItem, i, false, false);
                }
            }
            if (this._trackItem != -1)
            {
                command = this._drawCommands[this._trackItem] as DrawCommand;
                if (command.SubMenu)
                {
                    if (this._popupItem != this._trackItem)
                    {
                        if (this._childMenu != null)
                        {
                            WindowsAPI.PostMessage(this._childMenu.Handle, this.WM_DISMISS, 0, 0);
                        }
                        this.OperateSubMenu(this._trackItem, false);
                    }
                }
                else if (command.Expansion)
                {
                    this.RegenerateExpansion();
                }
                else
                {
                    if (this._childMenu != null)
                    {
                        WindowsAPI.PostMessage(this._childMenu.Handle, this.WM_DISMISS, 0, 0);
                    }
                    this._returnCommand = command.MenuCommand;
                    this._timer.Stop();
                    this._exitLoop = true;
                }
            }
        }

        protected void OperateSubMenu(int popupItem, bool selectFirst)
        {
            YidanSoft.Library.EditorUtility.Win32.POINT point;
            YidanSoft.Library.EditorUtility.Win32.POINT point2;
            this._popupItem = popupItem;
            this._childMenu = new PopupMenu();
            DrawCommand command = this._drawCommands[popupItem] as DrawCommand;
            point.x = command.DrawRect.Right;
            point.y = command.DrawRect.Top;
            WindowsAPI.ClientToScreen(base.Handle, ref point);
            point2.x = command.DrawRect.Left;
            point2.y = command.DrawRect.Top;
            WindowsAPI.ClientToScreen(base.Handle, ref point2);
            this._childMenu.Style = this.Style;
            this._childMenu.Font = this.Font;
            int returnDir = 0;
            this._returnCommand = this._childMenu.InternalTrackPopup(new Point(point.x, point.y), new Point(point2.x, point2.y), command.MenuCommand.MenuCommands, this, selectFirst, this._parentControl, this._popupRight, this._popupDown, ref returnDir);
            this._popupItem = -1;
            this._childMenu = null;
            if ((this._returnCommand != null) || (returnDir != 0))
            {
                this._timer.Stop();
                this._exitLoop = true;
                this._returnDir = returnDir;
            }
        }

        protected bool ParentWantsMouseMessage(ref YidanSoft.Library.EditorUtility.Win32.MSG msg)
        {
            YidanSoft.Library.EditorUtility.Win32.POINT point;
            point.x = ((int) msg.lParam) & 0xffff;
            point.y = (((int) msg.lParam) & -65536) >> 0x10;
            WindowsAPI.ClientToScreen(msg.hwnd, ref point);
            if ((msg.message == 0x200) && (this._parentControl != null))
            {
                YidanSoft.Library.EditorUtility.Win32.RECT rect = new YidanSoft.Library.EditorUtility.Win32.RECT();
                WindowsAPI.GetWindowRect(this._parentControl.Handle, ref rect);
                if ((((point.x >= rect.left) && (point.x <= rect.right)) && (point.y >= rect.top)) && (point.y <= rect.bottom))
                {
                    return true;
                }
            }
            return ((this._parentMenu != null) && this._parentMenu.WantMouseMessage(point));
        }

        protected bool ProcessKeyDown()
        {
            int newItem = this._trackItem;
            int num2 = newItem;
            for (int i = 0; i < this._drawCommands.Count; i++)
            {
                newItem++;
                if (newItem >= this._drawCommands.Count)
                {
                    newItem = 0;
                }
                DrawCommand command = this._drawCommands[newItem] as DrawCommand;
                if ((!command.Separator && command.Enabled) && (newItem != this._trackItem))
                {
                    this.SwitchSelection(this._trackItem, newItem, false, false);
                    return true;
                }
            }
            return false;
        }

        protected void ProcessKeyLeft()
        {
            if (this._trackItem != -1)
            {
                DrawCommand command = this._drawCommands[this._trackItem] as DrawCommand;
                int col = command.Col;
                int row = command.Row;
                if (col > 0)
                {
                    int newItem = -1;
                    int num4 = -1;
                    int num5 = col - 1;
                    DrawCommand command2 = null;
                    for (int i = 0; i < this._drawCommands.Count; i++)
                    {
                        DrawCommand command3 = this._drawCommands[i] as DrawCommand;
                        if ((command3.Col == num5) && ((((command3.Row <= row) && (command3.Row > num4)) && !command3.Separator) && command3.Enabled))
                        {
                            num4 = command3.Row;
                            command2 = command3;
                            newItem = i;
                        }
                    }
                    if (command2 != null)
                    {
                        this.SwitchSelection(this._trackItem, newItem, false, false);
                        return;
                    }
                }
                bool flag = (this._parentMenu == null) && (this._parentControl != null);
                if ((this._parentMenu != null) || flag)
                {
                    this._returnCommand = null;
                    this._timer.Stop();
                    this._exitLoop = true;
                    if (flag)
                    {
                        this._returnDir = -1;
                    }
                }
            }
        }

        protected bool ProcessKeyRight()
        {
            bool flag = this._parentControl != null;
            bool flag2 = false;
            bool flag3 = false;
            if (this._trackItem != -1)
            {
                DrawCommand command = this._drawCommands[this._trackItem] as DrawCommand;
                if (command.SubMenu)
                {
                    YidanSoft.Library.EditorUtility.Win32.MSG msg = new YidanSoft.Library.EditorUtility.Win32.MSG();
                    WindowsAPI.GetMessage(ref msg, 0, 0, 0);
                    this.OperateSubMenu(this._trackItem, true);
                    flag3 = true;
                }
                else
                {
                    int col = command.Col;
                    int row = command.Row;
                    int newItem = -1;
                    int num4 = -1;
                    int num5 = col + 1;
                    DrawCommand command2 = null;
                    for (int i = 0; i < this._drawCommands.Count; i++)
                    {
                        DrawCommand command3 = this._drawCommands[i] as DrawCommand;
                        if ((command3.Col == num5) && ((((command3.Row <= row) && (command3.Row > num4)) && !command3.Separator) && command3.Enabled))
                        {
                            num4 = command3.Row;
                            command2 = command3;
                            newItem = i;
                        }
                    }
                    if (command2 != null)
                    {
                        this.SwitchSelection(this._trackItem, newItem, false, false);
                    }
                    else
                    {
                        flag2 = true;
                    }
                }
            }
            else if (this._parentMenu != null)
            {
                if (!this.ProcessKeyDown())
                {
                    flag2 = true;
                }
            }
            else
            {
                flag2 = true;
            }
            if (flag && flag2)
            {
                this._returnCommand = null;
                this._timer.Stop();
                this._exitLoop = true;
                this._returnDir = 1;
            }
            return flag3;
        }

        protected bool ProcessKeyUp()
        {
            int newItem = this._trackItem;
            int num2 = newItem;
            for (int i = 0; i < this._drawCommands.Count; i++)
            {
                newItem--;
                if (newItem == num2)
                {
                    return false;
                }
                if (newItem < 0)
                {
                    newItem = this._drawCommands.Count - 1;
                }
                DrawCommand command = this._drawCommands[newItem] as DrawCommand;
                if ((!command.Separator && command.Enabled) && (newItem != this._trackItem))
                {
                    this.SwitchSelection(this._trackItem, newItem, false, false);
                    return true;
                }
            }
            return false;
        }

        protected int ProcessMnemonicKey(char key)
        {
            for (int i = 0; i < this._drawCommands.Count; i++)
            {
                DrawCommand command = this._drawCommands[i] as DrawCommand;
                if (command.Enabled && (key == command.Mnemonic))
                {
                    return i;
                }
            }
            return -1;
        }

        protected void RefreshAllCommands()
        {
            YidanSoft.Library.EditorUtility.Win32.RECT rect = new YidanSoft.Library.EditorUtility.Win32.RECT();
            WindowsAPI.GetWindowRect(base.Handle, ref rect);
            Rectangle rectWin = new Rectangle(0, 0, rect.right - rect.left, rect.bottom - rect.top);
            using (Graphics graphics = Graphics.FromHwnd(base.Handle))
            {
                this.DrawBackground(graphics, rectWin);
                this.DrawAllCommands(graphics);
            }
        }

        protected void RegenerateExpansion()
        {
            this._drawCommands.Clear();
            this._showInfrequent = true;
            Size winSize = this.GenerateDrawPositions();
            Point point = this.CorrectPositionForScreen(winSize);
            if (!this._layered)
            {
                this.SetWindowRegion(winSize);
                WindowsAPI.MoveWindow(base.Handle, point.X, point.Y, winSize.Width, winSize.Height, true);
            }
            else
            {
                this._currentPoint = point;
                this._currentSize = winSize;
                this.UpdateLayeredWindow();
            }
            this.RefreshAllCommands();
        }

        protected void ReturnTheFocus()
        {
            WindowsAPI.SetFocus(this._oldFocus);
            if (this._focusCatcher != null)
            {
                this._focusCatcher.DestroyHandle();
                this._focusCatcher = null;
            }
            this._oldFocus = IntPtr.Zero;
        }

        private void SetComboBoxesParent()
        {
            foreach (MenuCommand command in this._menuCommands)
            {
                if (command.ComboBox != null)
                {
                    WindowsAPI.SetParent(command.ComboBox.Handle, base.Handle);
                }
            }
        }

        protected void SetWindowRegion(Size winSize)
        {
            if (this._style == VisualStyle.IDE)
            {
                int height = _position[(int) this._style, 0x11];
                int width = _position[(int) this._style, 0x10];
                Region region = new Region();
                region.MakeInfinite();
                region.Xor(new Rectangle(winSize.Width - width, 0, width, height));
                if ((this._direction != Direction.Vertical) || this._excludeTop)
                {
                    region.Xor(new Rectangle(0, winSize.Height - height, width, height));
                }
                using (Graphics graphics = Graphics.FromHwnd(base.Handle))
                {
                    WindowsAPI.SetWindowRgn(base.Handle, region.GetHrgn(graphics), false);
                }
            }
        }

        protected void SubMenuMovement()
        {
            this._timer.Stop();
            if (this._popupItem != this._trackItem)
            {
                this.SwitchSelection(this._trackItem, this._popupItem, false, true);
            }
            if (this._parentMenu != null)
            {
                this._parentMenu.SubMenuMovement();
            }
        }

        protected void SwitchSelection(int oldItem, int newItem, bool mouseChange, bool reverting)
        {
            bool flag = false;
            using (Graphics graphics = Graphics.FromHwnd(base.Handle))
            {
                DrawCommand command;
                if (oldItem != -1)
                {
                    command = this._drawCommands[oldItem] as DrawCommand;
                    if (this._layered)
                    {
                        flag = true;
                    }
                    else
                    {
                        this.DrawSingleCommand(graphics, this._drawCommands[oldItem] as DrawCommand, false);
                    }
                }
                if (newItem != -1)
                {
                    this._timer.Stop();
                    if (!(reverting || (this._childMenu == null)))
                    {
                        this._timer.Start();
                    }
                    command = this._drawCommands[newItem] as DrawCommand;
                    if (!command.Separator && command.Enabled)
                    {
                        if (this._layered)
                        {
                            flag = true;
                        }
                        else
                        {
                            this.DrawSingleCommand(graphics, command, true);
                        }
                        if (!(reverting || !mouseChange))
                        {
                            this._timer.Start();
                        }
                    }
                    else
                    {
                        newItem = -1;
                    }
                }
                this._trackItem = newItem;
                if (this._layered && flag)
                {
                    this.UpdateLayeredWindow();
                }
            }
        }

        public MenuCommand TrackPopup(Point screenPos)
        {
            return this.TrackPopup(screenPos, false);
        }

        public MenuCommand TrackPopup(Point screenPos, bool selectFirst)
        {
            if (this._menuCommands.VisibleItems())
            {
                this._grabFocus = true;
                this._direction = Direction.Horizontal;
                this._screenPos = screenPos;
                this._aboveScreenPos = screenPos;
                this._leftScreenPos = screenPos;
                return this.InternalTrackPopup(selectFirst);
            }
            return null;
        }

        internal MenuCommand TrackPopup(Point screenPos, Point aboveScreenPos, Direction direction, MenuCommandCollection menuCollection, int borderGap, bool selectFirst, MenuControl parentControl, ref int returnDir)
        {
            this._direction = direction;
            this._parentControl = parentControl;
            this._borderGap = borderGap;
            MenuCommandCollection commands = this._menuCommands;
            this._menuCommands = menuCollection;
            this._screenPos = screenPos;
            this._aboveScreenPos = aboveScreenPos;
            this._leftScreenPos = screenPos;
            MenuCommand command = this.InternalTrackPopup(selectFirst);
            this._menuCommands = commands;
            this._parentControl = null;
            returnDir = this._returnDir;
            return command;
        }

        private void UnsetComboBoxesParent()
        {
            foreach (MenuCommand command in this._menuCommands)
            {
                if (command.ComboBox != null)
                {
                    command.ComboBox.Visible = false;
                    WindowsAPI.SetParent(command.ComboBox.Handle, IntPtr.Zero);
                }
            }
        }

        protected void UpdateLayeredWindow()
        {
            this.UpdateLayeredWindow(this._currentPoint, this._currentSize);
        }

        protected void UpdateLayeredWindow(Point point, Size size)
        {
            Bitmap image = new Bitmap(size.Width, size.Height, PixelFormat.Format32bppArgb);
            using (Graphics graphics = Graphics.FromImage(image))
            {
                YidanSoft.Library.EditorUtility.Win32.SIZE size2;
                YidanSoft.Library.EditorUtility.Win32.POINT point2;
                YidanSoft.Library.EditorUtility.Win32.POINT point3;
                Rectangle rectWin = new Rectangle(0, 0, size.Width, size.Height);
                this.DrawBackground(graphics, rectWin);
                this.DrawAllCommands(graphics);
                IntPtr dC = WindowsAPI.GetDC(IntPtr.Zero);
                IntPtr hDC = WindowsAPI.CreateCompatibleDC(dC);
                IntPtr hbitmap = image.GetHbitmap(Color.FromArgb(0));
                IntPtr hObject = WindowsAPI.SelectObject(hDC, hbitmap);
                size2.cx = size.Width;
                size2.cy = size.Height;
                point2.x = point.X;
                point2.y = point.Y;
                point3.x = 0;
                point3.y = 0;
                BLENDFUNCTION pblend = new BLENDFUNCTION();
                pblend.BlendOp = 0;
                pblend.BlendFlags = 0;
                pblend.SourceConstantAlpha = 0xff;
                pblend.AlphaFormat = 1;
                WindowsAPI.UpdateLayeredWindow(base.Handle, dC, ref point2, ref size2, hDC, ref point3, 0, ref pblend, 2);
                WindowsAPI.SelectObject(hDC, hObject);
                WindowsAPI.ReleaseDC(IntPtr.Zero, dC);
                WindowsAPI.DeleteObject(hbitmap);
                WindowsAPI.DeleteDC(hDC);
            }
        }

        protected bool WantMouseMessage(YidanSoft.Library.EditorUtility.Win32.POINT screenPos)
        {
            YidanSoft.Library.EditorUtility.Win32.RECT rect = new YidanSoft.Library.EditorUtility.Win32.RECT();
            WindowsAPI.GetWindowRect(base.Handle, ref rect);
            bool flag = (((screenPos.x >= rect.left) && (screenPos.x <= rect.right)) && (screenPos.y >= rect.top)) && (screenPos.y <= rect.bottom);
            if (!(flag || (this._parentMenu == null)))
            {
                flag = this._parentMenu.WantMouseMessage(screenPos);
            }
            return flag;
        }

        protected override void WndProc(ref Message m)
        {
            if (m.Msg == this.WM_DISMISS)
            {
                this.OnWM_DISMISS();
            }
            else
            {
                Debug.WriteLine(((Msg) m.Msg).ToString());
                switch (m.Msg)
                {
                    case 0x20:
                        this.OnWM_SETCURSOR(ref m);
                        return;

                    case 0x21:
                        this.OnWM_MOUSEACTIVATE(ref m);
                        return;

                    case 0x1c:
                        this.OnWM_ACTIVATEAPP(ref m);
                        return;

                    case 15:
                        this.OnWM_PAINT(ref m);
                        return;

                    case 520:
                    case 0x202:
                    case 0x205:
                        this.OnWM_XBUTTONUP(ref m);
                        return;

                    case 0x2a3:
                        this.OnWM_MOUSELEAVE();
                        return;

                    case 0x200:
                        this.OnWM_MOUSEMOVE(ref m);
                        return;
                }
                base.WndProc(ref m);
            }
        }

        [Category("Appearance")]
        public System.Drawing.Font Font
        {
            get
            {
                return this._textFont;
            }
            set
            {
                if (this._textFont != value)
                {
                    this._textFont = value;
                }
            }
        }

        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content), Category("Appearance")]
        public MenuCommandCollection MenuCommands
        {
            get
            {
                return this._menuCommands;
            }
            set
            {
                this._menuCommands.Clear();
                this._menuCommands = value;
            }
        }

        [Category("Behaviour"), DefaultValue(false)]
        public bool ShowInfrequent
        {
            get
            {
                return this._showInfrequent;
            }
            set
            {
                if (this._showInfrequent != value)
                {
                    this._showInfrequent = value;
                }
            }
        }

        [DefaultValue(0), Category("Appearance")]
        public VisualStyle Style
        {
            get
            {
                return this._style;
            }
            set
            {
                if (this._style != value)
                {
                    this._style = value;
                }
            }
        }

        protected enum ImageIndex
        {
            Check,
            Radio,
            SubMenu,
            CheckSelected,
            RadioSelected,
            SubMenuSelected,
            Expansion,
            ImageError
        }

        protected enum PI
        {
            BorderTop,
            BorderLeft,
            BorderBottom,
            BorderRight,
            ImageGapTop,
            ImageGapLeft,
            ImageGapBottom,
            ImageGapRight,
            TextGapLeft,
            TextGapRight,
            SubMenuGapLeft,
            SubMenuWidth,
            SubMenuGapRight,
            SeparatorHeight,
            SeparatorWidth,
            ShortcutGap,
            ShadowWidth,
            ShadowHeight,
            ExtraWidthGap,
            ExtraHeightGap,
            ExtraRightGap,
            ExtraReduce
        }
    }
}

